/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "Application.h"
#include "PQEngine.h"
#include "InputSystem.h"
#include "StateSystem.h"

namespace PQGame
{

	LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
	{
		switch (msg)
		{
		case WM_KEYDOWN:
			switch( wParam ){
			case VK_F1:
				//WindowsIME::getSingleton().nextIme();
				break;
			case VK_F2:
				//WindowsIME::getSingleton().changeImeSharp(hWnd);
				break;
			case VK_F3:
				//WindowsIME::getSingleton().changeImeSymbol(hWnd);
				break;
			case VK_F5:
				//WindowsIME::getSingleton().enableIme();
				break;
			case VK_F6:
				//WindowsIME::getSingleton().disableIme();
				break;
			}
			break;

		case WM_INPUTLANGCHANGEREQUEST:
			//bool ret= WindowsIME::getSingleton().OnWM_INPUTLANGCHANGEREQUEST()?0:DefWindowProc(hWnd,msg,wParam,lParam);
			//return ret;
		case WM_INPUTLANGCHANGE:
			//WindowsIME::getSingleton().OnWM_INPUTLANGCHANGE(hWnd);
			//drawFrame(hWnd);
			break;

		case WM_IME_NOTIFY:
			//WindowsIME::getSingleton().OnWM_IME_NOTIFY(hWnd,wParam);
			//drawFrame(hWnd);
			return 0;

		case WM_IME_COMPOSITION:
			//WindowsIME::getSingleton().OnWM_IME_COMPOSITION(hWnd,lParam,g_Str);
			//drawFrame(hWnd);
			return 0;

		case WM_IME_SETCONTEXT: 
		case WM_IME_STARTCOMPOSITION:
		case WM_IME_ENDCOMPOSITION:
			//drawFrame( hWnd );
			return 0;

		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		default:
			return DefWindowProc(hWnd, msg, wParam, lParam);
		}

		return 0;
	}

	Application::Application(void)
		: isRunning(true)
	{
	}

	Application::~Application(void)
	{
	}

	Application& Application::getSingleton()
	{
		static Application app;
		return app;
	}
	
	Ogre::String Application::createWindow(HINSTANCE hInst,int ncmdshow)
	{
		WNDCLASSEX winclass;
        HWND hwnd;

        winclass.cbSize = sizeof(WNDCLASSEX);
        winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        winclass.lpfnWndProc = WindowProc;
        winclass.cbClsExtra = 0;
        winclass.cbWndExtra = 0;
        winclass.hInstance = hInst;
        winclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
        winclass.hCursor = LoadCursor(NULL,IDC_ARROW);
		winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        winclass.lpszMenuName = NULL;
        winclass.lpszClassName = "WINCLASS1";
        winclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);

        RegisterClassEx(&winclass);
        
        if(!(hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
        "WINCLASS1",
        "PQWorld",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0,0,
        800,600,
        NULL,
        NULL,
		hInst,
        NULL))){ 
                ShowWindow(hwnd,ncmdshow);
                UpdateWindow (hwnd);
        }

		return Ogre::StringConverter::toString((size_t)hwnd);
	}

	void Application::init(HINSTANCE hInst,int ncmdshow)
	{
		Ogre::String hWnd=createWindow(hInst,ncmdshow);
		
		
		_sceneObject=SEngine.createSceneObject(hWnd,800,600);

		InputSystem::getSingleton().init(_sceneObject);
		StateSystem::getSingleton().init(_sceneObject);

		lastTime=timer.getMilliseconds();
		
	}

	void Application::start()
	{
		MSG msg;
		while(GetMessage(&msg, NULL, 0, 0)&&isRunning){
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			update();
		}
	}

	void Application::update()
	{
		Ogre::Real deltaT=(timer.getMilliseconds()-lastTime)/1000.0f;
		lastTime=timer.getMilliseconds();
		StateSystem::getSingleton().update(deltaT);
		InputSystem::getSingleton().capture();
		SEngine.renderOneFrame(_sceneObject);
		
	}

	void Application::shutdown()
	{
		isRunning=false;
	}
}
